package com.yxy.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.yxy.common.PageResult;
import com.yxy.constant.MessageConstant;
import com.yxy.constant.StatusConstant;
import com.yxy.context.BaseContext;
import com.yxy.exception.AccountNotFoundException;
import com.yxy.exception.AccountAlreadyExistsException;
import com.yxy.exception.AccountNotAvailableException;
import com.yxy.exception.PasswordErrorException;
import com.yxy.exception.ServerErrorException;
import com.yxy.mapper.AdminMapper;
import com.yxy.pojo.dto.AdminDTO;
import com.yxy.pojo.dto.AdminLoginDTO;
import com.yxy.pojo.dto.AdminPageQueryDTO;
import com.yxy.pojo.entity.Admin;
import com.yxy.pojo.vo.AdminPageQueryVO;
import com.yxy.properties.AESProperties;
import com.yxy.service.AdminService;
import com.yxy.utils.AESUtil;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private AESProperties aesProperties;

    /**
     * 管理员登录
     *
     * @param adminLoginDTO
     * @return
     */
    @Override
    public Admin login(AdminLoginDTO adminLoginDTO) {
        String username = adminLoginDTO.getAdminUname();
        String password = adminLoginDTO.getAdminPwd();
        // 先判断账号是否存在
        Admin admin = adminMapper.selectByUname(username);
        if (admin == null) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        // 判断账号是否可用
        if (admin.getStatus() == StatusConstant.DISABLE) {
            throw new AccountNotAvailableException(MessageConstant.ACCOUNT_NOT_AVAILABLE);
        }
        // 将前端密码加密，与数据库密码进行比对
        try {
            String encrypt = AESUtil.encrypt(password, aesProperties.getSecretKey());
            if (!encrypt.equals(admin.getAdminPwd())) {
                throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
            }
        } catch (Exception e) {
            throw new ServerErrorException(MessageConstant.PASSWORD_ERROR);
        }
        // 都没问题后，记录本次登陆时间和上次登陆时间
        // 判断是否是第一次登陆，若是则本次和上次时间一致
        if (admin.getLastLoginTime() == null) {
            admin.setLastLoginTime(LocalDateTime.now());
            admin.setCurrentLoginTime(LocalDateTime.now());
        } else {
            // 否则将原本的登陆时间记为上次登陆时间，当前时间记为本次登陆时间
            admin.setLastLoginTime(admin.getCurrentLoginTime());
            admin.setCurrentLoginTime(LocalDateTime.now());
        }
        adminMapper.setLoginTime(admin);
        return admin;
    }

    /**
     * 根据id查询管理员信息
     * @param id
     * @return
     */
    @SneakyThrows
    @Override
    public Admin getAdminInfoById(int id) {
        Admin admin = adminMapper.selectById(id);
        // 密码解密
        String password = AESUtil.decrypt(admin.getAdminPwd(), aesProperties.getSecretKey());
        admin.setAdminPwd(password);
        return admin;
    }

    /**
     * 分页查询管理员信息
     * @param adminPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(AdminPageQueryDTO adminPageQueryDTO) {
        PageHelper.startPage(adminPageQueryDTO.getPage(), adminPageQueryDTO.getPageSize());
        Page<AdminPageQueryVO> page = adminMapper.pageQuery(adminPageQueryDTO);
        page.getResult().forEach(admin -> {
            try {
                String password = AESUtil.decrypt(admin.getAdminPwd(), aesProperties.getSecretKey());
                admin.setAdminPwd(password);
            } catch (Exception e) {
                throw new ServerErrorException(MessageConstant.SERVER_ERROR);
            }
        });
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 批量删除管理员
     * @param ids
     */
    @Override
    public void batchDelete(List<Integer> ids) {
        adminMapper.deleteByIds(ids);
    }

    /**
     * 修改管理员信息
     * @param adminDTO
     */
    @SneakyThrows
    @Override
    public void update(AdminDTO adminDTO) {
        Admin admin = new Admin();
        BeanUtils.copyProperties(adminDTO, admin);
        if(admin.getAdminPwd() != null){
            admin.setAdminPwd(AESUtil.encrypt(admin.getAdminPwd(), aesProperties.getSecretKey()));
        }
        admin.setUpdateUser(BaseContext.getCurrentId());
        admin.setUpdateTime(LocalDateTime.now());
        adminMapper.update(admin);
    }

    /**
     * 修改管理员状态
     * @param id
     * @param status
     */
    @Override
    public void updateStatus(int id, int status) {
        adminMapper.updateStatus(id, status);
    }

    /**
     * 添加管理员
     * @param adminDTO
     */
    @SneakyThrows
    @Override
    public void add(AdminDTO adminDTO) {
        // 判断用户名是否存在
        Admin a = adminMapper.selectByUname(adminDTO.getAdminUname());
        if(a != null){
            throw new AccountAlreadyExistsException(MessageConstant.ACCOUNT_ALREADY_EXISTS);
        }
        Admin admin = Admin.builder()
                .adminUname(adminDTO.getAdminUname())
                .adminPwd(adminDTO.getAdminPwd())
                .nickname(adminDTO.getNickname())
                .phone(adminDTO.getPhone())
                .gender(adminDTO.getGender())
                .avatar(adminDTO.getAvatar())
                .createTime(LocalDateTime.now())
                .createUser(BaseContext.getCurrentId())
                .status(StatusConstant.ENABLE)
                .build();
        admin.setAdminPwd(AESUtil.encrypt(admin.getAdminPwd(), aesProperties.getSecretKey()));
        adminMapper.insert(admin);
    }
}
